let LF = 10, //换行  line feed
  CR = 13, //回车 carriage return
  SPACE = 32, //空格
  COLON = 58; //冒号
let PARSER_UNINITIALIZED = 0, //未解析
  START = 1, //开始解析
  REQUEST_LINE = 2, // 分析请求行
  HEADER_FIELD_START = 3, // 分析请求头（ header）
  HEADER_FIELD = 4,
  HEADER_VALUE_START = 5,
  HEADER_VALUE = 6,
  READING_BODY = 7;
class Parser {
  constructor() {
    this.state = PARSER_UNINITIALIZED;
  }
  parse(buffer) {
    let self = this,
      requestLine = "",
      headers = {},
      body = "",
      i = 0,
      char,
      state = START, //开始解析
      headerField = "",
      headerValue = "";
    // console.log(buffer.toString());
    for (i = 0; i < buffer.length; i++) {
      char = buffer[i];
      switch (state) {
        case START:
          state = REQUEST_LINE; // 分析请求行
          self["requestLineMark"] = i; // 请求行开头字母标记
        case REQUEST_LINE:
          if (char == CR) {
            //换行
            //POST /post HTTP/1.1   0~19 获取请求行
            requestLine = buffer.toString("utf8", self["requestLineMark"], i);
            break;
          } else if (char == LF) {
            //回车
            state = HEADER_FIELD_START; // 分析请求头（header）
          }
          break;
        case HEADER_FIELD_START:
          if (char === CR) {
            state = READING_BODY; // 剩下的就是body的数据了
            self["bodyMark"] = i + 2;
            break;
          } else {
            state = HEADER_FIELD;
            self["headerFieldMark"] = i;
          }
        case HEADER_FIELD:
          if (char == COLON) { // 判断冒号，是不是已经获取到了key
            headerField = buffer.toString("utf8", self["headerFieldMark"], i);
            state = HEADER_VALUE_START;
          }
          break;
        case HEADER_VALUE_START:
          if (char == SPACE) {
            break;
          }
          self["headerValueMark"] = i;
          state = HEADER_VALUE;
        case HEADER_VALUE:
          if (char === CR) { //如果是换行符，代表已经获取到了value
            headerValue = buffer.toString("utf8", self["headerValueMark"], i);
            headers[headerField] = headerValue;
            headerField = "";
            headerValue = "";
          } else if (char === LF) {
            state = HEADER_FIELD_START;
          }
          break;
        default:
          break;
      }
    }
    let [method, url] = requestLine.split(" ");
    // console.log(self["bodyMark"], i, JSON.stringify(buffer.toString("utf8", self["bodyMark"], i)))
    body = buffer.toString("utf8", self["bodyMark"], i);
    return {
      method,
      url,
      headers,
      body,
    };
  }
}
module.exports = Parser;
